#pragma once

#include <Arduino.h>
#include <vector>

#include "ax25.h"

/**
 * @brief 无线电接收帧缓存
 *
 * rxTimeMs   表示收到有效帧的时间戳（millis）
 * infoText   以 ASCII 解码后的信息字段（无法解析时可能为空）
 */
struct RadioFrame {
  Ax25Frame ax25;
  unsigned long rxTimeMs = 0;
  String infoText;
};

/**
 * @brief 初始化射频子系统（ADC 采样 + PWM 调制 + PTT 控制）
 *
 * @param pinSpkIn  手台扬声器音频输入 ADC 引脚
 * @param pinMicOut 输出至手台 MIC 的 PWM 引脚
 * @param pinPtt    PTT 控制引脚（高电平触发）
 */
void radioInit(int pinSpkIn, int pinMicOut, int pinPtt);

/**
 * @brief 在主循环中周期调用，用于执行采样解码与事件分发
 */
void radioHandle();

/**
 * @brief 发送已经构建好的 AX.25 原始帧（需包含 FCS，不含 FLAG）
 *
 * @return true 发送流程执行成功
 */
bool radioSendAx25(const std::vector<uint8_t> &frame);

/**
 * @brief 快捷函数：根据当前位置构建 APRS 位置报文并射频发送
 */
bool radioSendAprsPosition(const String &callsign,
                           float latitude,
                           float longitude,
                           char symbolTable,
                           char symbolCode,
                           const String &comment);

/**
 * @brief 快捷函数：发送 APRS 文本消息（UI 帧 :DEST:TEXT 格式）
 *
 * @param callsign 本台呼号
 * @param target   目的呼号（自动填充到 9 字符宽的消息字段）
 * @param text     消息正文（超长会自动截断为 67 字符以内）
 * @param msgId    可选消息序号（"" 为不附带，形如 "001"）
 */
bool radioSendAprsMessage(const String &callsign,
                          const String &target,
                          const String &text,
                          const String &msgId = String());

/**
 * @brief 若存在未读取的接收帧，则取出一份
 */
bool radioFetchFrame(RadioFrame &frame);

/**
 * @brief 最近一次成功解码的 APRS 文本（便于 UI 显示）
 */
String radioLastInfoText();
unsigned long radioLastInfoMillis();

/**
 * @brief 接收统计：成功/失败帧计数
 */
unsigned long radioDecodeSuccessCount();
unsigned long radioDecodeErrorCount();
